



import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats

# 尝试导入statsmodels，处理兼容性问题
try:
    import statsmodels.api as sm
    use_statsmodels = True
except ImportError as e:
    if '_lazywhere' in str(e):
        print("警告: statsmodels与当前SciPy版本不兼容，将跳过回归分析部分")
        use_statsmodels = False
    else:
        raise

# 设置随机种子确保可复现
np.random.seed(42)

# 生成示例数据
data = pd.DataFrame({
    'exam_score': np.random.normal(70, 10, 200),  # 正态分布的考试成绩
    'study_hours': np.random.uniform(1, 10, 200),  # 均匀分布的学习时间
    'coffee_cups': np.random.poisson(3, 200),  # 泊松分布的咖啡杯数
    'passed': np.random.binomial(1, 0.7, 200)  # 二项分布的通过情况
})

# 添加学习时间的二次项模拟非线性关系
data['study_hours_sq'] = data['study_hours'] ** 2
data['exam_score'] = data['exam_score'] + 2 * data['study_hours'] - 0.1 * data['study_hours_sq']

# 添加缺失值
data.iloc[10:15, 0] = np.nan

# 1. 概率分布分析
fig, axes = plt.subplots(2, 2, figsize=(12, 10))

# 正态分布示例
sns.histplot(data['exam_score'], kde=True, ax=axes[0, 0], stat='density')
axes[0, 0].set_title('考试成绩分布（正态）')

# 泊松分布示例
sns.histplot(data['coffee_cups'], discrete=True, stat='probability', ax=axes[0, 1])
axes[0, 1].set_title('咖啡消耗量（泊松）')

# 均匀分布示例
sns.histplot(data['study_hours'], kde=True, ax=axes[1, 0], stat='density')
axes[1, 0].set_title('学习时间（均匀）')

# 二项分布示例
sns.countplot(x='passed', data=data, ax=axes[1, 1])
axes[1, 1].set_title('考试通过情况（二项）')

plt.tight_layout()
plt.show()

# 概率计算示例
prob_above_80 = np.mean(data['exam_score'] > 80)  # 成绩>80的概率
prob_3_coffee = np.mean(data['coffee_cups'] == 3)  # 恰好喝3杯咖啡的概率

print(f"成绩>80的概率: {prob_above_80:.2%}")
print(f"恰好喝3杯咖啡的概率: {prob_3_coffee:.2%}")

# 正态分布概率计算
mean_score = data['exam_score'].mean()
std_score = data['exam_score'].std()
z_score = (80 - mean_score) / std_score
prob_z = 1 - stats.norm.cdf(z_score)

print(f"使用正态分布计算的成绩>80概率: {prob_z:.2%}")

# 2. 参数估计
# 点估计
mean_estimate = data['exam_score'].mean()
median_estimate = data['exam_score'].median()
std_estimate = data['exam_score'].std()

print(f"\n点估计结果:")
print(f"平均成绩估计值: {mean_estimate:.2f}")
print(f"成绩中位数: {median_estimate:.2f}")
print(f"成绩标准差: {std_estimate:.2f}")

# 区间估计 (95% CI)
confidence = 0.95
n = len(data['exam_score'].dropna())
se = std_estimate / np.sqrt(n)
ci_low, ci_high = stats.t.interval(confidence, n-1, loc=mean_estimate, scale=se)

print(f"\n95%置信区间: ({ci_low:.2f}, {ci_high:.2f})")

# 比例估计 (通过率)
pass_rate = data['passed'].mean()
pass_se = np.sqrt(pass_rate * (1 - pass_rate) / len(data))
pass_ci_low = pass_rate - 1.96 * pass_se
pass_ci_high = pass_rate + 1.96 * pass_se

print(f"\n通过率估计: {pass_rate:.2%}")
print(f"通过率95%CI: ({pass_ci_low:.2%}, {pass_ci_high:.2%})")

# 3. 假设检验
# 单样本t检验 (平均成绩是否等于75)
t_stat, p_value = stats.ttest_1samp(data['exam_score'].dropna(), 75)
print(f"\n单样本t检验 (H0: μ=75):")
print(f"t统计量: {t_stat:.4f}, p值: {p_value:.4f}")
print("结论: " + ("拒绝H0" if p_value < 0.05 else "无法拒绝H0"))

# 双样本t检验 (喝咖啡≤2杯 vs >2杯的成绩差异)
group1 = data[data['coffee_cups'] <= 2]['exam_score']
group2 = data[data['coffee_cups'] > 2]['exam_score']
t_stat, p_value = stats.ttest_ind(group1, group2, nan_policy='omit')

print(f"\n双样本t检验 (咖啡消耗量对成绩的影响):")
print(f"低咖啡组平均: {group1.mean():.2f}, 高咖啡组平均: {group2.mean():.2f}")
print(f"t统计量: {t_stat:.4f}, p值: {p_value:.4f}")

# 卡方检验 (咖啡消耗与通过率是否独立)
contingency_table = pd.crosstab(data['coffee_cups'], data['passed'])
chi2, p_value, dof, expected = stats.chi2_contingency(contingency_table)

print(f"\n卡方检验 (咖啡消耗与通过率):")
print(f"卡方值: {chi2:.4f}, p值: {p_value:.4f}")

# 4. 回归分析（仅在statsmodels可用时执行）
if use_statsmodels:
    # 数据预处理
    clean_data = data.dropna().copy()

    # 简单线性回归 (学习时间 vs 考试成绩)
    X = clean_data[['study_hours']]
    y = clean_data['exam_score']
    X = sm.add_constant(X)  # 添加截距项

    model = sm.OLS(y, X).fit()
    print("\n简单线性回归结果:")
    print(model.summary())

    # 可视化回归结果
    plt.figure(figsize=(10, 6))
    sns.regplot(x='study_hours', y='exam_score', data=clean_data, line_kws={'color': 'red'})
    plt.title('学习时间与考试成绩关系')
    plt.show()

    # 多元线性回归 (加入二次项和咖啡消耗)
    X_multi = clean_data[['study_hours', 'study_hours_sq', 'coffee_cups']]
    X_multi = sm.add_constant(X_multi)  # 添加截距项

    multi_model = sm.OLS(y, X_multi).fit()
    print("\n多元线性回归结果:")
    print(multi_model.summary())

    # 逻辑回归 (预测通过概率)
    X_logit = clean_data[['study_hours', 'coffee_cups']]
    X_logit = sm.add_constant(X_logit)  # 添加截距项
    y_pass = clean_data['passed']

    logit_model = sm.Logit(y_pass, X_logit).fit()
    print("\n逻辑回归结果:")
    print(logit_model.summary())

    # 可视化逻辑回归结果
    plt.figure(figsize=(10, 6))
    sns.scatterplot(x='study_hours', y='passed', data=clean_data, alpha=0.5)
    sns.lineplot(x=clean_data['study_hours'], y=logit_model.predict(X_logit), color='red')
    plt.title('学习时间与通过概率关系')
    plt.ylabel('通过概率')
    plt.show()
else:
    print("\n跳过回归分析部分（需要兼容的statsmodels）")